from django.core.exceptions import ObjectDoesNotExist
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.db import transaction
from django.core.mail import send_mail
from . import forms, backEnd
from django.contrib.auth import authenticate, login, logout
from datetime import datetime, timedelta
from django.utils import timezone

# 实现 用户中心 centre
from django.shortcuts import render, get_object_or_404
from blog.models import Article
# from blog.models import *
from comment.models import Comment
from .models import User, Follow

import re
import json
from django.shortcuts import redirect
# 用于响应前台AJAX调用
from django.http import JsonResponse
# 实现关注与粉丝列表，单独实现，也可以迁移到用户中心中
from django.views.generic import ListView


def index(request):
    return render(request, "user/index.html")


def SquareView(request):
    query = request.GET.get('query')  # 获取查询参数

    if query:  # 如果存在查询参数
        users = User.objects.filter(nickname__icontains=query)  # 使用查询参数过滤用户
        is_search = True  # 标记为搜索结果页面
    else:
        users = User.objects.all()  # 否则获取所有用户
        is_search = False  # 标记为非搜索结果页面

    return render(request, "user/square.html", {'users': users, 'is_search': is_search, 'query': query})


def loginView(request):
    if request.user.is_authenticated:
        # 也许这需要调整代码结构，避免狮山代码，每次都要写一次path太麻烦了
        path = "/user/centre/" + request.user.username
        return HttpResponseRedirect(path)
    if request.method == 'POST':
        form = forms.LoginForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data['username']
            password = form.cleaned_data['password']
        try:
            user = authenticate(request, username=username, password=password)
            print(user.registerTime)
            if user is not None:
                login(request, user)
                path = "/user/centre/" + user.username
                return HttpResponseRedirect(path)
            else:
                error_message = "用户名或密码错误"
        except:
            error_message = "用户名或密码错误"
        return render(
            request,
            'user/login.html',
            {'error_message': error_message, 'form': form}
        )
    else:
        form = forms.LoginForm(request.POST)
        return render(request, 'user/login.html', {'form': form})


def logoutView(request):
    logout(request)
    return HttpResponseRedirect("/user/login/")


def sendEmailCodeView(request):
    print('send email code view 被调用')
    if request.method == 'POST':
        email = request.POST.get('email')

        # 添加邮箱唯一性验证
        # 检查邮箱的唯一性
        if User.objects.filter(email=email).exists():
            return JsonResponse({'status': 'error', 'message': '该邮箱已被注册'})

        # 在这里生成验证码、发送邮件，并将验证码存储到会话中
        email_code = backEnd.SendCaptcha(email)
        request.session['email_code'] = email_code
        # request.session['email_code_time'] = datetime.now()  # 设置初始值为当前时间

        return JsonResponse({'status': 'success'})
    else:
        return JsonResponse({'status': 'success'})


def registerView(request):
    error_message = ""  # 初始化错误信息为空，Django 不推荐使用None
    current_time = datetime.now()
    print(type(current_time))

    if request.method == 'POST':
        with transaction.atomic():
            form = forms.RegisterForm(request.POST)
            if form.is_valid():
                username = form.cleaned_data['username']
                password = form.cleaned_data['password']
                repassword = form.cleaned_data['repassword']
                nickname = form.cleaned_data['nickname']
                email = form.cleaned_data['email']

                # 验证邮箱验证码
                user_email_code = form.cleaned_data['email_code']
                session_email_code = request.session.get('email_code', '')

                if user_email_code != session_email_code:
                    error_message = "邮箱验证码不正确"
                    return render(request, 'user/register.html', {'form': form, 'error_message': error_message})

                # 验证通过后清除会话中的验证码
                del request.session['email_code']
                # del request.session['email_code_time']


                # 检查用户名和密码长度
                if len(username) < 6 or len(password) < 6:
                    error_message = "用户名和密码必须至少包含 6 个字符"
                    return render(request, 'user/register.html', {'form': form, 'error_message': error_message})
                # 检查用户名和密码是否符合规则
                elif not re.match(r'^[\w]+$', username):
                    error_message = "用户名只能包含字母、数字和下划线"
                    return render(request, 'user/register.html', {'form': form, 'error_message': error_message})
                elif not re.match(r'^[\w]+$', password):
                    error_message = "密码只能包含字母、数字和下划线"
                    return render(request, 'user/register.html', {'form': form, 'error_message': error_message})
                # 检查用户名是否已存在
                elif User.objects.filter(username=username).exists():
                    error_message = "用户名已存在，请选择其他用户名"
                    return render(request, 'user/register.html', {'form': form, 'error_message': error_message})
                elif password != repassword:
                    error_message = "两次输入的密码不相同，请检查后重新输入。"
                    return render(request, 'user/register.html', {'form': form, 'error_message': error_message})
                else:  # 创建成功
                    # 创建用户对象并设置注册时间，然后保存到数据库中
                    new_user = User.objects.create_user(
                        username=username,
                        email=email,
                        password=password,
                        nickname=nickname,
                        registerTime=current_time)
                    # 注册成功重定向到登录页面
                    return HttpResponseRedirect("/user/logout")

            # print(username, password)
            # return render(request, 'user/register.html', {'form': form})
    else:
        form = forms.RegisterForm(request.POST)  # 传递POST请求中的数据给表单
    return render(request, 'user/register.html', {'form': form, 'error_message': error_message})

# 用户中心实现
# 按理说不需要要求登录
# @login_required
def centreView(request, usrname):
    try:
        current_user = request.user  # 获取当前登录用户
        if not current_user.is_authenticated:
            return HttpResponseRedirect("/user/login/")
        requested_user = get_object_or_404(User, username=usrname)  # 获取请求的用户

        following = [fo.to_user for fo in Follow.objects.filter(from_user=requested_user)]
        followers = [fo.from_user for fo in Follow.objects.filter(to_user=requested_user)]
        # print(following)
        # print(followers)

        # 获取请求用户的文章列表
        user_articles = Article.objects.filter(author=requested_user, status='P')

        return render(request, 'user/centre.html', {
            # 'user_avatar': user_avatar,  # 假设有 avatar 字段用于用户头像
            'requested_user': requested_user,
            'current_user': current_user,
            'following': following,
            'followers': followers,
            'user_articles': user_articles,
            # 其他需要传递给模板的信息
        })
    except User.DoesNotExist:
        return render(request, 'user/user_not_found.html')


# 实现关注功能
@login_required
@transaction.atomic
def follow_usr(request, usrname):
    try:
        requested_user = get_object_or_404(User, username=usrname)
        current_user = request.user  # 获取当前登录用户

        if request.method == 'POST':
            # 获取或创建关注关系实例
            follow_instance, created = Follow.objects.get_or_create(
                from_user=current_user,
                to_user=requested_user
            )

            # 如果关注关系已存在，删除关注
            if not created:
                follow_instance.delete()

            return redirect('centre', usrname=usrname)  # 返回个人中心页面
    except User.DoesNotExist:
        pass

    return redirect('centre', usrname=usrname)  # 处理其他情况，返回个人中心页面


from django.db.models import Q


def searchView(request, usrname):
    query = request.GET.get('query')
    requested_user = get_object_or_404(User, username=usrname)  # 获取当前用户中心的主人
    current_user = request.user  # 获取当前登录用户

    if query:
        # 执行搜索逻辑，搜索标题、摘要和正文包含搜索词的文章
        search_results = Article.objects.filter(
            Q(author=requested_user) & (
                    Q(title__icontains=query) |
                    Q(abstract__icontains=query) |
                    Q(body__icontains=query)
            )
        )
    else:
        search_results = None

    return render(request, 'user/search_results.html', {
        'search_results': search_results,
        'usrname': usrname,
        'current_user': current_user,
        'query': query,
    })


# follower是指关注者,fans，而Following是被关注者。
# 所以，FollowersListView 应该返回关注当前用户的人列表，而 FollowingListView 应该返回当前用户关注的人列表。
class FollowersListView(ListView):
    model = Follow
    template_name = 'user/followers_list.html'  # 创建一个模板用于显示粉丝列表
    context_object_name = 'followers'

    def get_queryset(self):
        requested_user = get_object_or_404(User, username=self.kwargs.get('usrname'))
        temp = Follow.objects.filter(to_user=requested_user)  # 获取粉丝列表
        return temp

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        usrname = self.kwargs.get('usrname')  # 获取 URL 中的 usrname 参数
        context['requested_user'] = get_object_or_404(User, username=usrname)
        return context


class FollowingListView(ListView):
    model = Follow
    template_name = 'user/following_list.html'  # 创建一个模板用于显示关注列表
    context_object_name = 'following'

    def get_queryset(self):
        requested_user = get_object_or_404(User, username=self.kwargs.get('usrname'))
        temp = Follow.objects.filter(from_user=requested_user)  # 获取关注列表
        return temp

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        usrname = self.kwargs.get('usrname')  # 获取 URL 中的 usrname 参数
        context['requested_user'] = get_object_or_404(User, username=usrname)
        return context


# 实现用户编辑个人信息功能
@login_required
@transaction.atomic
def edit_user_info(request, usrname):
    error_message = ""  # 初始化错误信息为空
    # print('requestuser:')
    # print(request.user)
    # print('usrname:')
    # print(usrname)

    # 获取访问的用户对象
    try:
        accessed_user = User.objects.get(username=usrname)
    except User.DoesNotExist:
        return HttpResponse("用户不存在或未授权访问")  # 如果用户不存在则返回拒绝页面

    # 检查当前登录用户和访问用户是否匹配
    if request.user != accessed_user:
        return HttpResponse("无权编辑其他用户信息")  # 如果不匹配则返回拒绝页面

    if request.method == 'POST':
        # username = request.POST.get('username')
        nickname = request.POST.get('nickname')
        password = request.POST.get('password')

        current_time = datetime.now()
        username = request.user.username  # 获取当前登录用户的用户名

        # 检查密码规则
        if len(password) < 6:
            error_message = "修改失败！密码必须至少包含 6 个字符，如不更改密码，请输入原密码"
            return render(request, 'user/edit.html', {'error_message': error_message})
        elif not re.match(r'^[\w]+$', password):
            error_message = "修改失败！密码只能包含字母、数字和下划线"
            return render(request, 'user/edit.html', {'error_message': error_message})
        # 检查昵称不能为空且不能含有空格
        if not nickname or ' ' in nickname:
            error_message = "修改失败！昵称不能为空且不能包含空格"
            return render(request, 'user/edit.html', {'error_message': error_message})
        else:  # 通过验证，进行修改操作
            new_user = User.objects.get(username=request.user.username)
            # 更新 User 模型中的用户名
            new_user.username = username
            new_user.set_password(password)
            new_user.nickname = nickname
            new_user.save()
            # 重定向到用户中心或其他页面
            return HttpResponseRedirect("/user/login")

    return render(request, 'user/edit.html', {'error_message': error_message})

# 忽略这个函数
def emailVerifyView(request):
    # 用户请求获取验证码
    # del request.session['capt_expires_at']
    if True or request.method == 'POST':
        '''
        检查距离上次获取请求的时间差是否超过一分钟
        '''
        capt_expires_at = request.session.get('capt_expires_at')
        if capt_expires_at and datetime.fromisoformat(json.loads(capt_expires_at)) >= datetime.now():
            print('无法频繁发送验证码')
            # TODO
        captcha = backEnd.GenCaptcha()
        send_mail(
                    subject='test',
                    message=captcha,
                    from_email=None,
                    recipient_list=['1336211227@qq.com']
                 )
        # 会话保存验证码和上次验证码生成时间
        request.session['captcha'] = captcha
        request.session['capt_expires_at'] = json.dumps(datetime.now() + timedelta(minutes=1), default=str)
    # 暂时不确定验证码发送后该咋办，也许要通过Ajax交互？
    return HttpResponseRedirect("/user/login")


def is_username_matching_email(username, email):
    try:
        user = User.objects.get(username=username)
        return user.email == email and len(user.email)==len(email)
    except User.DoesNotExist:
        return False


# 忘记密码，用于发送验证码的视图函数
def ForgetPwdSendEmailCodeView(request):
    if request.method == 'POST':
        email = request.POST.get('email')
        username = request.POST.get('username')  # 添加获取用户名的逻辑

        # 在这里验证用户名与邮箱是否匹配
        if is_username_matching_email(username, email):
            # 用户名与邮箱匹配，继续生成验证码、发送邮件，并将验证码存储到会话中
            email_code = backEnd.SendCaptcha(email)
            request.session['email_code'] = email_code
            return JsonResponse({'status': 'success'})
        else:
            return JsonResponse({'status': 'error', 'message': '用户名与邮箱不匹配'})
    else:
            return JsonResponse({'status': 'error', 'message': 'Invalid request method'})


def ForgetPasswordView(request):
    if request.method == 'POST':
        form = forms.PasswordResetForm(request.POST)
        if form.is_valid():
            if form.is_valid():
                username = form.cleaned_data['username']
                password = form.cleaned_data['password']
                repassword = form.cleaned_data['repassword']
                email = form.cleaned_data['email']
                user_email_code = form.cleaned_data['email_code']

                try:
                    user = User.objects.get(username=username, email=email)
                except User.DoesNotExist:
                    error_message = "提供的用户名或邮箱不匹配"
                    return render(request, 'user/forget_password.html', {'form': form, 'error_message': error_message})

                # 验证邮箱验证码
                session_email_code = request.session.get('email_code', '')

                if user_email_code != session_email_code:
                    error_message = "邮箱验证码不正确"
                    return render(request, 'user/register.html', {'form': form, 'error_message': error_message})

                # 验证通过后清除会话中的验证码
                del request.session['email_code']

                # 检查密码长度
                if len(password) < 6:
                    error_message = "密码必须至少包含 6 个字符"
                    return render(request, 'user/forget_password.html', {'form': form, 'error_message': error_message})
                # 检查密码是否符合规则
                elif not re.match(r'^[\w]+$', password):
                    error_message = "密码只能包含字母、数字和下划线"
                    return render(request, 'user/forget_password.html', {'form': form, 'error_message': error_message})
                elif password != repassword:
                    error_message = "两次输入的密码不相同，请检查后重新输入。"
                    return render(request, 'user/forget_password.html', {'form': form, 'error_message': error_message})
                else:
                    # 修改用户密码
                    user.set_password(password)
                    user.save()

                    # 注册成功重定向到登录页面
                    return HttpResponseRedirect("/user/logout")
    else:
        form = forms.PasswordResetForm()

    return render(request, 'user/forget_password.html', {'form': form})
